/**
 * Copyright (c) www.longdw.com
 */
package com.jdy.haoduoaiteacher.lyric;

import com.jdy.haoduoaiteacher.util.Tools;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LyricLoadHelper {

  private static final String TAG = LyricLoadHelper.class.getSimpleName();

  /** 句子集合 */
  private final List<LyricSentence> mLyricSentences = new ArrayList<LyricSentence>();

  private LyricListener mLyricListener = null;

  private final boolean mHasLyric = true;

  /** 当前正在播放的歌词句子的在句子集合中的索引号 */
  private int mIndexOfCurrentSentence = -1;

  private final String mEncoding = "utf-8";

  // 用于缓存的一个正则表达式对象
  private static final Pattern pattern = Pattern.compile("(?<=\\[).*?(?=\\])");

  public List<LyricSentence> getLyricSentences() {
    return mLyricSentences;
  }

  public void setLyricListener(LyricListener listener) {
    this.mLyricListener = listener;
  }

  public void setIndexOfCurrentSentence(int index) {
    mIndexOfCurrentSentence = index;
  }

  public int getIndexOfCurrentSentence() {
    return mIndexOfCurrentSentence;
  }

  /**
   * 根据歌词文件的路径，读取出歌词文本并解析
   * 
   * @param lyricPath
   *          歌词文件路径
   * @return true表示存在歌词，false表示不存在歌词
   */
  public void loadLyric(String lyricPath) {
    File file = new File(lyricPath);
    BufferedReader br = null;
    try {
      br = new BufferedReader(new InputStreamReader(new FileInputStream(file),
          "UTF-8"));
      StringBuilder sb = new StringBuilder();
      String temp = null;
      while ((temp = br.readLine()) != null) {

        sb.append(temp).append("\n");
      }
      init(sb.toString());
      // 如果有谁在监听，通知它歌词载入完啦，并把载入的句子集合也传递过去
      if (mLyricListener != null) {
        mLyricListener.onLyricLoaded(mLyricSentences, 0);
      }
    } catch (Exception ex) {
      Logger.getLogger(Lyric.class.getName()).log(Level.SEVERE, null, ex);

    } finally {
      try {
        br.close();
      } catch (Exception ex) {
        Logger.getLogger(Lyric.class.getName()).log(Level.SEVERE, null, ex);
      }
    }
  }

  private void init(String content) {
    // 如果歌词的内容为空,则后面就不用执行了
    // 直接显示歌曲名就可以了
    if (content == null || content.trim().equals("")) {
      return;
    }
    try {
      BufferedReader br = new BufferedReader(new StringReader(content));
      String temp = null;
      while ((temp = br.readLine()) != null) {
        parseLine(temp.trim());
      }
      appendEndLine();
      br.close();
      // 读进来以后就排序了
      Collections.sort(mLyricSentences, new Comparator<LyricSentence>() {

        @Override
        public int compare(LyricSentence o1, LyricSentence o2) {
          return (int) (o1.getStartTime() - o2.getStartTime());
        }
      });
      int size = mLyricSentences.size();
      for (int i = 0; i < size; i++) {
        LyricSentence next = null;
        if (i + 1 < size) {
          next = mLyricSentences.get(i + 1);
        }
        LyricSentence now = mLyricSentences.get(i);
        if (next != null) {
          now.setToTime(next.getStartTime() - 1);
        }
      }
    } catch (Exception ex) {
      Logger.getLogger(Lyric.class.getName()).log(Level.SEVERE, null, ex);
    }
  }

  private void appendEndLine() {
    String content = new String("(完)");
    long endFromTime = mLyricSentences.get(mLyricSentences.size() - 1)
        .getStartTime() + 2000;
    mLyricSentences.add(new LyricSentence(endFromTime, content));
  }

  /**
   * 根据传递过来的已播放的毫秒数，计算应当对应到句子集合中的哪一句，再通知监听者播放到的位置。
   * 
   * @param millisecond
   *          已播放的毫秒数
   */
  public void notifyTime(long millisecond) {
    // Log.i(TAG, "notifyTime");
    if (mHasLyric && mLyricSentences != null && mLyricSentences.size() != 0) {
      int newLyricIndex = seekSentenceIndex(millisecond);
      if (newLyricIndex != -1 && newLyricIndex != mIndexOfCurrentSentence) {// 如果找到的歌词和现在的不是一句。
        if (mLyricListener != null) {
          // 告诉一声，歌词已经变成另外一句啦！
          mLyricListener.onLyricSentenceChanged(newLyricIndex);
        }
        mIndexOfCurrentSentence = newLyricIndex;
      }
    }
  }

  private int seekSentenceIndex(long t) {
    for (int i = 0; i < mLyricSentences.size(); i++) {
      if (mLyricSentences.get(i).isInTime(t)) {
        return i;
      }
    }
    if (t <= mLyricSentences.get(0).getStartTime())
      return 0;
    else if (t >= mLyricSentences.get(mLyricSentences.size() - 1).getToTime())
      return mLyricSentences.size() - 1;
    else
      return -1;
  }

  /** 解析每行歌词文本,一行文本歌词可能对应多个时间戳 */
  private void parseLine(String line) {
    if (line.equals("")) {
      return;
    }
    int hasBracket = line.indexOf("[");
    int hasBackBracket = line.indexOf("]");
    if (hasBracket != -1 && hasBackBracket == -1) {
      line = line.replace("[", "");
    } else if (hasBracket == -1 && hasBackBracket != -1) {
      line = line.replace("]", "");
    }

    String s = null, content = null;
    Matcher matcher = pattern.matcher(line);
    int lastIndex = -1;// 最后一个时间标签的下标
    if (matcher.find()) {
      s = matcher.group();
      lastIndex = line.indexOf("]");
      content = line.substring(lastIndex + 1, line.length());

    } else {
      String reg = "[\u4e00-\u9fa5]";
      if (line.matches(".*" + reg + ".*")) {
        lastIndex = line.split(reg)[0].length();
        s = line.substring(0, lastIndex);
        content = line.substring(lastIndex, line.length());
      }
    }
    long t = parseTime(s);
    if (t != -1)
      mLyricSentences.add(new LyricSentence(t, content));
  }

  private long parseTime(String strTime) {
    if (Tools.isEmpty(strTime)) {
      return -1;
    }

    String[] ss = strTime.split("\\:|\\.");
    // 如果 是两位以后，就非法了
    if (ss.length < 2) {
      return -1;
    } else if (ss.length == 2) {// 如果正好两位，就算分秒
      try {
        int min = Integer.parseInt(ss[0]);
        int sec = Integer.parseInt(ss[1]);
        if (min < 0 || sec < 0 || sec >= 60) {
          throw new RuntimeException("数字不合法!");
        }
        // System.out.println("time" + (min * 60 + sec) * 1000L);
        return (min * 60 + sec) * 1000L;
      } catch (Exception exe) {
        return -1;
      }
    } else if (ss.length == 3) {// 如果正好三位，就算分秒，十毫秒
      try {
        int min = Integer.parseInt(ss[0]);
        int sec = Integer.parseInt(ss[1]);
        int mm = Integer.parseInt(ss[2]);
        if (min < 0 || sec < 0 || sec >= 60 || mm < 0 || mm > 999) {
          throw new RuntimeException("数字不合法!");
        }
        // System.out.println("time" + (min * 60 + sec) * 1000L + mm *
        // 10);
        return (min * 60 + sec) * 1000L + mm;
      } catch (Exception exe) {
        return -1;
      }
    } else {// 否则也非法
      return -1;
    }
  }

}
